use ferris_says::say; // from the previous step
use std::{collections::btree_map::Values, io::{stdout, BufWriter}};
fn main() {
    let stdout = stdout();
    let message = String::from("Hello fellow Rustaceans!");
    let width = message.chars().count();

    let mut writer = BufWriter::new(stdout.lock());
    say(&message, width, &mut writer).unwrap();
    
    let a = String::from("hello world");
    let b = get_size(a);
    println!("{}", b);
  //  println!("{}", a);
    let c = "hello world".to_string();
    get_sliceString(c);

    get_struct();

    get_struct_fn();

    get_enum_match();

    get_vector();

    get_string();
}

fn get_size(a: String) -> usize {
    a.len()
}

fn get_sliceString(b: String){
    let m = &b[0..7];
    println!("m is {}",m);

    let world = &b[6..11];
    println!(" world is {}",world);
}


fn get_struct(){
    //定义结构体
    //自动推到
    #[derive(Debug)]
    struct User {
        name: String,
        count: String,
        nonce: u64,
        active: bool,
    }
    //实现结构体
    let xiaoming = User{
        name: String::from("xiaoming"),
        count: String::from("87655678"),
        nonce: 10000,
        active: true,
    };
    //修改结构体
    let mut xiaohuang = User{
        name: String::from("xiaoming"),
        count: String::from("87655678"),
        nonce: 10000,
        active: true,
    };

    xiaohuang.nonce = 20000;

    //参数名字和字段名字同名的简写方法
    let nam11e = String::from("xiaoxiao");
    let count1 = String::from("123123");
    let nonce1 = 1111;
    let active1 = false;

    let user1 = User{
        name: nam11e,
        count: count1,
        nonce: nonce1,
        active: active1,
    };

    //从其他结构体创建 新的结构体
    let user2 = User{
        name: String::from("hujianfeng"),
        ..user1
    };
    println!("user2 name is {0}",user2.name);   

    //元祖结构体 1. 用圆括号 2. 没有字段名字
    struct point(i32,i32);
    let a = point(10,20);
    let b = point(30,40);
    println!("a x is {} and a y is {}",a.0,a.1);
    
    //没有内容的结构体
    struct A{};

    //打印结构体
    println!("user2 is {:?}",user2);
    println!("user2 is {:#?}",user2);
}


fn get_struct_fn(){
    #[derive(Debug)]
    struct Dog{
        name: String,
        weigth: f32,
        length: f32,
    }

    impl Dog{
        fn get_weigth(&self) -> f32{
            self.weigth
        }
        fn get_length(&self) -> f32{
            self.length
        }
        fn get_name(&self) -> &String{
            &self.name
        }
        fn show(&self){
            println!("{} :wang wang wang ",self.name);
        }
        
    }

    let dog = Dog{
       name: String::from("wangcai"),
       weigth: 10.0,
       length: 20.0,
    };

    println!("dog is {:?} ",dog);
    println!("dog's name  is {} ",dog.get_name());
    println!("dog's weight  is {} ",dog.get_weigth());
    println!("dog's length  is {} ",dog.get_length());
    dog.show();

}

fn get_enum_match(){
    //1. 类似C的定义方式
    #[derive(Debug)]
    enum IpAddrKind{
        V4,
        V6,
    }
    
    struct IpAddr{
        kind: IpAddrKind,
        address: String,
    }

    let i1 = IpAddr{
        kind: IpAddrKind::V4,
        address: String::from("10.0.1.10")
    };
    let i2 = IpAddr{
        kind: IpAddrKind::V6,
        address: String::from("::1")
    };

    //2. rust 提倡的方式
    enum IpAddr2{
        V4(String),
        V6(String)
    }

    let i1 = IpAddr2::V4(String::from("127.0.0.1"));
    let i2 = IpAddr2::V4(String::from("::1"));

    //3. 枚举的每个值都可以有自己的数据类型
    enum IpAddr3{
        v4(u8,u8,u8,u8),
        V6(String)
    }

    let i1 = IpAddr3::v4(127,0,0,1);
    let i2 = IpAddr3::V6(String::from("::1"));

    //4 枚举经典用法 状态机
    enum Message{
        Quit,
        Move{x:i32,y:i32},
        Write(String),
        ChangeColor(i32,i32,i32),
    }

    impl Message {
        fn prin(&self){
            match self {
                Message::Quit=> println!("Quit"),
                //注意这里的括号  元组 圆括号   结构体 大括号  
                Message::Move{x,y}=> println!("Move x is {0} y is {1}",x,y),
                Message::Write(s)=> println!("Write is {0}",s),
                Message::ChangeColor(r,g,b)=> println!("ChangeColor r is {0} g is {1} b is {2}",r,g,b),
            }
        }
    }

    let m1 = Message::Quit;
    m1.prin();

    let m2 = Message::Write(String::from("hello world"));
    m2.prin();
}


fn get_vector(){
    let mut v: Vec<i32>  = Vec::new();
    v.push(11);

    let v = vec![1,2,3];

    let one :&i32 = &v[2];
    // print!("one is  {}",one);
    // print!("one is  {}",*one);

    match v.get(1) {
        Some(value)=>println!("value = {}",value),
        None =>println!("Node")
    };
    #[derive(Debug)]
    enum COntext {
        Text(String),
        Float(f32),
        Int(i32),
    };

    let c = vec![
        COntext::Text(String::from("hel2222lo")),
        COntext::Int(-1),
        COntext::Float(10.001)
    ];

    match c.get(0) {
        Some(vv )=>println!("value is {:?}",vv),
        None=>println!("None")
    }
}


fn get_string(){
    //1.創建空字符串
    let mut str = String::new();
    str.push_str("string");
    println!("{}" ,str);
}